package com.sandking.net;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;

import com.sandking.metadata.SK_Cfg;
import com.sandking.net.pojo.NetClass;
import com.sandking.net.pojo.NetField;
import com.sandking.net.pojo.NetMethod;
import com.sandking.net.template.NTP;
import com.sandking.tools.SK_Plus;

import freemarker.ext.beans.BeansWrapper;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;

public class NetGenerate {
	String path = "";
	public static final String Server = "server";
	public static final String Client = "client";
	public static final String NetObject = "netObj";
	public static final String NetGenerate = "netGen";

	private static Configuration cfg;

	public static Configuration getConfiguration() {
		if (cfg == null) {
			cfg = new Configuration();
			cfg.setClassForTemplateLoading(NTP.class, "");
			cfg.setObjectWrapper(new DefaultObjectWrapper());
		}
		return cfg;
	}

	public static Configuration getConfiguration(String path) {
		if (cfg == null) {
			try {
				cfg = new Configuration();
				cfg.setDirectoryForTemplateLoading(new File(path));
				cfg.setObjectWrapper(new BeansWrapper());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return cfg;
	}

	public NetGenerate(String path) {
		super();
		this.path = path;
	}

	public String getPath() {
		return path;
	}

	public void setPath(String path) {
		this.path = path;
	}

	/**
	 * 生成服务器接口
	 * 
	 * @param server
	 * @throws NotFoundException
	 * @throws ClassNotFoundException
	 */
	public void runServer(Object server, Configuration cfg, String name)
			throws NotFoundException, ClassNotFoundException {
		examinePackage(SK_Plus.b(path, "/", Server).e());
		String packageName = "";
		ClassPool pool = ClassPool.getDefault();
		CtClass cc = pool.getCtClass(server.getClass().getName());
		List<NetMethod> methods = new ArrayList<NetMethod>();
		CtMethod[] ctMethods = cc.getDeclaredMethods();
		for (CtMethod ctMethod : ctMethods) {
			NetMethod netMethod = new NetMethod();
			NetAnnotation netAnnotation = (NetAnnotation) ctMethod
					.getAnnotation(NetAnnotation.class);
			netMethod.setRemark(netAnnotation.remark());
			methods.add(netMethod);
		}

		List<NetField> fields = new ArrayList<NetField>();
		NetClass netClass = new NetClass(packageName, name, methods, fields);
		writerCmdParse(name, cfg, netClass);
	}

	/**
	 * 生成客户端接口
	 * 
	 * @param client
	 */
	public void runClient(Object client) {

	}

	/**
	 * 生成网络传输对象
	 * 
	 * @param netObject
	 */
	public void runNetObject(Object netObject) {

	}

	/**
	 * 生成常量对象
	 * 
	 * @param constantObject
	 */
	public void runConstantObject(Object constantObject) {

	}

	public void examinePackage(String path) {
		File file = new File(path);
		if (!file.exists() || !file.isDirectory()) {
			file.mkdir();
		}

	}

	private static void writerCmdParse(String path, Configuration cfg,
			NetClass clazzs) {
		String filePath = path + "/DbSave.java";
		String packageName = path.replace("src/", "").replace("/", ".");
		// SK_Cfg skCfg = new SK_Cfg("DbSave", packageName, tables);
		File file = new File(filePath);
		try {
			Template template = cfg.getTemplate("dbSave.ftl");
			// fileWriter(template, file, skCfg);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private static void fileWriter(Template template, File file, Object table) {
		try {
			FileWriter fileWriter = new FileWriter(file);
			template.process(table, fileWriter);
			fileWriter.flush();
			// 打印输出
			Writer writer = new OutputStreamWriter(System.out);
			template.process(table, writer);
			writer.flush();
			System.out.println();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void completeInfo() {
		System.out.println("*********************************************");
		System.out.println("*                                           *");
		System.out.println("**********代码生成完成-请刷新项目！**********");
		System.out.println("*                                           *");
		System.out.println("*********************************************");
	}
}
